package com.smartcampus.demo.mqtt;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.smartcampus.demo.domain.Gas;
import com.smartcampus.demo.domain.Humidity;
import com.smartcampus.demo.domain.Temperature;
import com.smartcampus.demo.service.GasService;
import com.smartcampus.demo.service.HumidityService;
import com.smartcampus.demo.service.TemperatureService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
public class PushCallback implements MqttCallback {
    @Autowired
    private MqttConfiguration mqttConfiguration;

    @Autowired
    @Lazy
    private MqttPushClient mqttPushClient;

    @Autowired
    private GasService gasService;

    @Autowired
    private HumidityService humidityService;

    @Autowired
    private TemperatureService temperatureService;

    // 阈值设置
    private static final double GAS_THRESHOLD = 10;
    private static final double TEMPERATURE_THRESHOLD = 28.0;
    private static final double HUMIDITY_THRESHOLD = 70.0;
    private static final double RAIN_THRESHOLD = 0.7;
    private static final int LIGHT_THRESHOLD = 116;
    private static final int PEOPLE_THRESHOLD = 1952;
    private static final int DISTANCE_THRESHOLD = 5;
    // 状态管理
    private final ConcurrentHashMap<String, Boolean> sensorStates = new ConcurrentHashMap<>();


    @Override
    public void connectionLost(Throwable cause) {        // 连接丢失后，一般在这里面进行重连
        log.info("连接断开，正在重连");
        MqttPushClient mqttPushClient = mqttConfiguration.getMqttPushClient();
        if (null != mqttPushClient) {
            mqttPushClient.connect(mqttConfiguration.getHost(), mqttConfiguration.getClientid(), mqttConfiguration.getUsername(),
                    mqttConfiguration.getPassword(), mqttConfiguration.getTimeout(), mqttConfiguration.getKeepalive());
            log.info("已重连");
        }

    }

    /**
     * 发送消息，消息到达后处理方法
     * @param token
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {

    }

    /**
     * 订阅主题接收到消息处理方法
     * @param topic
     * @param message
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) {
        // subscribe后得到的消息会执行到这里面,这里在控制台有输出
        log.info("接收消息主题 : " + topic);
        log.info("接收消息Qos : " + message.getQos());
        log.info("接收消息内容 : " + new String(message.getPayload()));

        // 解析消息内容为 JSON
        try {
            String messageContent = new String(message.getPayload());
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> data = objectMapper.readValue(messageContent, Map.class);

            // 根据主题判断消息类型并处理
            switch (topic) {
                case "smartroom/report/gas":
                    handleGasMessage(data);
                    break;
                case "smartroom/report/temp-humi":
                    handleTempHumiMessage(data);
                    break;
                case "smartroom/report/rain":
                    handleRainMessage(data);
                    break;
                case "smartroom/report/light":
                    handleLightMessage(data);
                    break;
                case "smartroom/report/people":
                    handlePeopleMessage(data);
                    break;
                case "smartroom/report/distance":
                    handleDistanceMessage(data);
                    break;
                default:
                    log.info("未知主题: " + topic);
            }
        } catch (Exception e) {
            log.error("消息解析或处理失败", e);
        }
    }

    /**
     * 处理 gas 消息
     * @param data 消息数据
     */
    private void handleGasMessage(Map<String, Object> data) {
        try {
            String gasValue = data.get("gas").toString();
            double gas = Double.parseDouble(gasValue);

            // 保存数据到数据库
            Gas gasData = new Gas();
            gasData.setValue(gas);
            gasService.saveGas(gasData);


            boolean currentState = gas < GAS_THRESHOLD;
            boolean previousState = sensorStates.getOrDefault("gas", false);

            if (currentState) {
                if (!previousState) {
                    // 状态从正常变为异常，发送“打开警报”
                    sendWarningMessage("buzzer");
                } else {
                    // 状态持续异常，继续发送“打开警报”
                    sendWarningMessage("buzzer");
                }
            } else {
                if (previousState) {
                    // 状态从异常变为正常，发送“关闭警报”
                    sendRecoveryMessage("stopbuz");
                }
                // 状态持续正常，不发送消息
            }

            sensorStates.put("gas", currentState);
        } catch (Exception e) {
            log.error("处理 gas 消息失败", e);
        }
    }

    /**
     * 处理温度和湿度消息
     * @param data 消息数据
     */
    private void handleTempHumiMessage(Map<String, Object> data) {
        try {
            double temperature = (double) data.get("temperature");
            double humidity = (double) data.get("humidity");

            Humidity humidityData= new Humidity();
            humidityData.setValue(humidity);
            humidityService.saveHumidity(humidityData);

            Temperature temperatureData = new Temperature();
            temperatureData.setValue(temperature);
            temperatureService.saveTemperature(temperatureData);

            boolean tempState = temperature > TEMPERATURE_THRESHOLD;
            boolean previousTempState = sensorStates.getOrDefault("temperature", false);
//
//            if (tempState) {
//                if (!previousTempState) {
//                    // 状态从正常变为异常，发送“开风扇”
//                    sendWarningMessage("fanopen");
//                } else {
//                    // 状态持续异常，继续发送“开风扇”
//                    sendWarningMessage("fanopen");
//                }
//            } else {
//                if (previousTempState) {
//                    // 状态从异常变为正常，发送“关风扇”
//                    sendRecoveryMessage("fanclose");
//                }
//                // 状态持续正常，不发送消息
//            }

            sensorStates.put("temperature", tempState);

            boolean humiState = humidity > HUMIDITY_THRESHOLD;
            boolean previousHumiState = sensorStates.getOrDefault("humidity", false);

            // 这里只是示例，您可以根据需要添加湿度的处理逻辑
            sensorStates.put("humidity", humiState);
        } catch (Exception e) {
            log.error("处理 temperature 和 humidity 消息失败", e);
        }
    }

    /**
     * 处理雨量消息
     * @param data 消息数据
     */
    private void handleRainMessage(Map<String, Object> data) {
        try {
            String rainValue = data.get("rain").toString();
            double rain = Double.parseDouble(rainValue);

            boolean currentState = rain > RAIN_THRESHOLD;
            boolean previousState = sensorStates.getOrDefault("rain", false);

            if (currentState) {
                if (!previousState) {
                    // 状态从正常变为异常，发送“关闭窗帘”
                    sendWarningMessage("right");
                } else {
                    // 状态持续异常，继续发送“关闭窗帘”
                    sendWarningMessage("right");
                }
            } else {
                if (previousState) {
                    // 状态从异常变为正常，发送“打开窗帘”
                    sendRecoveryMessage("left");
                }
                // 状态持续正常，不发送消息
            }

            sensorStates.put("rain", currentState);
        } catch (Exception e) {
            log.error("处理 rain 消息失败", e);
        }
    }

    /**
     * 处理光照消息
     * @param data 消息数据
     */
    private void handleLightMessage(Map<String, Object> data) {
        try {
            String lightValue = data.get("light").toString();
            int light = Integer.parseInt(lightValue);

            boolean currentState = light > LIGHT_THRESHOLD;
            boolean previousState = sensorStates.getOrDefault("light", false);

//            if (currentState) {
//                if (!previousState) {
//                    // 状态从正常变为异常，发送“关闭灯”
//                    sendWarningMessage("ledclose");
//                } else {
//                    // 状态持续异常，继续发送“关闭灯”
//                    sendWarningMessage("ledclose");
//                }
//            } else {
//                if (previousState) {
//                    // 状态从异常变为正常，发送“打开灯”
//                    sendRecoveryMessage("ledopen");
//                }
//                // 状态持续正常，不发送消息
//            }

            sensorStates.put("light", currentState);
        } catch (Exception e) {
            log.error("处理 light 消息失败", e);
        }
    }

    /**
     * 处理人员消息
     * @param data 消息数据
     */
    private void handlePeopleMessage(Map<String, Object> data) {
        try {
            String peopleValue = data.get("people").toString();
            int people = Integer.parseInt(peopleValue);

            boolean currentState = people > PEOPLE_THRESHOLD;
            boolean previousState = sensorStates.getOrDefault("people", false);
//
//            if (currentState) {
//                if (!previousState) {
//                    // 状态从正常变为异常，发送“打开警报”
//                    sendWarningMessage("buzzer");
//                } else {
//                    // 状态持续异常，继续发送“打开警报”
//                    sendWarningMessage("buzzer");
//                }
//            } else {
//                if (previousState) {
//                    // 状态从异常变为正常，发送“关闭警报”
//                    sendRecoveryMessage("stopbuz");
//                }
//                // 状态持续正常，不发送消息
//            }


            // 这里只是示例，您可以根据需要添加人员的处理逻辑
            sensorStates.put("people", currentState);
        } catch (Exception e) {
            log.error("处理 people 消息失败", e);
        }
    }

    /**
     * 处理距离消息
     * @param data 消息数据
     */
    private void handleDistanceMessage(Map<String, Object> data) {
        // 添加处理逻辑
        try {


            String distanceValue = data.get("distance").toString();
            double distance = Double.parseDouble(distanceValue);
//            double distance = Integer.parseInt(distanceValue);

            boolean currentState = distance < DISTANCE_THRESHOLD;
            boolean previousState = sensorStates.getOrDefault("distance", false);

            if (currentState) {
                if (!previousState) {
                    // 状态从正常变为异常，发送“打开警报”
                    sendWarningMessage("left");
                } else {
                    // 状态持续异常，继续发送“打开警报”
                    sendWarningMessage("left");
                }
            } else {
                if (previousState) {
                    // 状态从异常变为正常，发送“关闭警报”
                    sendRecoveryMessage("right");
                }
                // 状态持续正常，不发送消息
            }


            sensorStates.put("distance", currentState);
        } catch (Exception e) {
            log.error("处理 distance 消息失败", e);
        }
    }

    /**
     * 发送警告消息
     * @param message 警告消息内容
     */
    private void sendWarningMessage(String message) {
        log.info("发送警告消息: {}", message);
        mqttPushClient.publish("smartroom/control", message);
    }

    /**
     * 发送恢复消息
     * @param message 恢复消息内容
     */
    private void sendRecoveryMessage(String message) {
        log.info("发送恢复消息: {}", message);
        mqttPushClient.publish("smartroom/control", message);
    }
}